﻿#include "lifemanagewindow.h"

LifeManageWindow::LifeManageWindow(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);
	ui.action_active->setIcon(QApplication::style()->standardIcon(QStyle::SP_DialogYesButton));
	ui.action_unactive->setIcon(QApplication::style()->standardIcon(QStyle::SP_DialogNoButton));
	ui.action_init->setIcon(QApplication::style()->standardIcon(QStyle::SP_BrowserReload));
	ui.action_unload->setIcon(QApplication::style()->standardIcon(QStyle::SP_DialogCancelButton));
	ui.action_load->setIcon(QApplication::style()->standardIcon(QStyle::SP_ArrowForward));

	connect(ui.action_active, SIGNAL(triggered()), this, SLOT(btnActive_clicked()));
	connect(ui.action_init, SIGNAL(triggered()), this, SLOT(btnInit_clicked()));
	connect(ui.action_unactive, SIGNAL(triggered()), this, SLOT(btnUnActive_clicked()));
	connect(ui.action_unload, SIGNAL(triggered()), this, SLOT(btnUnLoad_clicked()));
	connect(ui.action_load, SIGNAL(triggered()), this, SLOT(btnLoad_clicked()));

	ui.tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
	ui.tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);  //不可编辑
	ui.tableView->setSelectionBehavior(QAbstractItemView::SelectRows); //设置选中模式为选中行
}

LifeManageWindow::~LifeManageWindow()
{
}

void LifeManageWindow::setData(const vector<SerLoad> &vecSerLoad, const vector<ViewLoad> &vecViewLoad, const QMap<QString, ILoadManager *> &loadmap)
{
	mSerLoadData = vecSerLoad;
	mViewLoadData = vecViewLoad;
	mILoadManager = loadmap;
	ui.tableView->setModel(getModel());
}
QStandardItemModel *LifeManageWindow::getModel()
{
	mModel = new QStandardItemModel(ui.tableView);
	mModel->setHorizontalHeaderLabels(QStringLiteral("组件名|实例名|状态").split("|"));
	int currentRow = 0;
	for (auto it = mSerLoadData.begin(); it != mSerLoadData.end(); it++, currentRow++)
	{
		QString comName = QString::fromStdString(it->compName);
		QString instanceName = QString::fromStdString(it->instanceName);
		QStandardItem *item1 = new QStandardItem(comName);
		QStandardItem *item2 = new QStandardItem(instanceName);
		QStandardItem *item3 = new QStandardItem(mILoadManager.value(comName)->QueryState(instanceName));
		item3->setTextAlignment(Qt::AlignCenter);
		item2->setData(QVariant::fromValue(SerLoadType), Qt::UserRole);							   //代表存的是SerLoad
		item2->setData(QVariant::fromValue(distance(mSerLoadData.begin(), it)), Qt::UserRole + 1); //存储在SerLoad数组里的下标
		mModel->setItem(currentRow, ComponentName_Column, item1);
		mModel->setItem(currentRow, InstanceName_Column, item2);
		mModel->setItem(currentRow, InstanceState_Column, item3);
	}
	for (auto it = mViewLoadData.begin(); it != mViewLoadData.end(); it++, currentRow++)
	{
		QString comName = QString::fromStdString(it->pluginName);
		QString instanceName = QString::fromStdString(it->instanceName);
		QStandardItem *item1 = new QStandardItem(comName);
		QStandardItem *item2 = new QStandardItem(instanceName);
		QStandardItem *item3 = new QStandardItem(mILoadManager.value(comName)->QueryState(instanceName));
		item3->setTextAlignment(Qt::AlignCenter);
		item2->setData(QVariant::fromValue(ViewLoadType), Qt::UserRole);							//代表存的是ViewLoad
		item2->setData(QVariant::fromValue(distance(mViewLoadData.begin(), it)), Qt::UserRole + 1); //存储在ViewLoad数组里的下标
		mModel->setItem(currentRow, ComponentName_Column, item1);
		mModel->setItem(currentRow, InstanceName_Column, item2);
		mModel->setItem(currentRow, InstanceState_Column, item3);
	}
	return mModel;
}

void LifeManageWindow::btnInit_clicked()
{
	//获取选中的条目
	auto rows = getSelectedRows();
	for (auto it = rows.begin(); it != rows.end(); it++)
	{
		//检查选中的条目的当前状态是否满足执行条件
		bool isOk = checkState(*it, QStringLiteral("Loaded"), QStringLiteral("初始化"));
		if (!isOk)
		{
			return;
		}
		//执行操作
		QString dllName = mModel->item(*it, ComponentName_Column)->text();
		QString instanceName = mModel->item(*it, InstanceName_Column)->text();
		mILoadManager.value(dllName)->Init(instanceName);
		//改变界面
		mModel->item(*it, InstanceState_Column)->setText(mILoadManager.value(dllName)->QueryState(instanceName));
	}
}
void LifeManageWindow::btnUnLoad_clicked()
{
	//获取选中的条目
	auto rows = getSelectedRows();
	for (auto it = rows.begin(); it != rows.end(); it++)
	{
		//检查选中的条目的当前状态是否满足执行条件
		bool isOk = checkState(*it, QStringLiteral("UnActivated/Loaded"), QStringLiteral("释放"));
		if (!isOk)
		{
			return;
		}
		//执行操作
		QString dllName = mModel->item(*it, ComponentName_Column)->text();
		QString instanceName = mModel->item(*it, InstanceName_Column)->text();
		mILoadManager.value(dllName)->UnLoad(instanceName);
		//改变界面
		mModel->item(*it, InstanceState_Column)->setText(mILoadManager.value(dllName)->QueryState(instanceName));
	}
}
void LifeManageWindow::btnLoad_clicked()
{
	//获取选中的条目
	auto rows = getSelectedRows();
	for (auto it = rows.begin(); it != rows.end(); it++)
	{
		//检查选中的条目的当前状态是否满足执行条件
		bool isOk = checkState(*it, QStringLiteral("UnLoaded"), QStringLiteral("加载"));
		if (!isOk)
		{
			return;
		}
		//执行操作
		QString dllName = mModel->item(*it, ComponentName_Column)->text();
		QString instanceName = mModel->item(*it, InstanceName_Column)->text();
		//从model里取出携带的数据
		auto loadType = mModel->item(*it, InstanceName_Column)->data(Qt::UserRole).value<LoadType>(); //load类型
		auto loadIndex = mModel->item(*it, InstanceName_Column)->data(Qt::UserRole + 1).toInt();	  //在数组中的下标
		void *pLoad = nullptr;
		if (loadType == SerLoadType)
		{
			pLoad = static_cast<void *>(&mSerLoadData.at(loadIndex));
		}
		else if (loadType == ViewLoadType)
		{
			pLoad = static_cast<void *>(&mViewLoadData.at(loadIndex));
		}
		mILoadManager.value(dllName)->Load(pLoad);
		//改变界面
		mModel->item(*it, InstanceState_Column)->setText(mILoadManager.value(dllName)->QueryState(instanceName));
	}
}
void LifeManageWindow::btnActive_clicked()
{
	//获取选中的条目
	auto rows = getSelectedRows();
	for (auto it = rows.begin(); it != rows.end(); it++)
	{
		//检查选中的条目的当前状态是否满足执行条件
		bool isOk = checkState(*it, QStringLiteral("Initialized/UnActivated/UnLoaded"), QStringLiteral("激活"));
		if (!isOk)
		{
			return;
		}
		//执行操作
		QString dllName = mModel->item(*it, ComponentName_Column)->text();
		QString instanceName = mModel->item(*it, InstanceName_Column)->text();
		mILoadManager.value(dllName)->Active(instanceName);
		//改变界面
		mModel->item(*it, InstanceState_Column)->setText(mILoadManager.value(dllName)->QueryState(instanceName));
	}
}
void LifeManageWindow::btnUnActive_clicked()
{
	//获取选中的条目
	auto rows = getSelectedRows();
	for (auto it = rows.begin(); it != rows.end(); it++)
	{
		//检查选中的条目的当前状态是否满足执行条件
		bool isOk = checkState(*it, QStringLiteral("Activated"), QStringLiteral("去活"));
		if (!isOk)
		{
			return;
		}
		//执行操作
		QString dllName = mModel->item(*it, ComponentName_Column)->text();
		QString instanceName = mModel->item(*it, InstanceName_Column)->text();
		mILoadManager.value(dllName)->UnActive(instanceName);
		//改变界面
		mModel->item(*it, InstanceState_Column)->setText(mILoadManager.value(dllName)->QueryState(instanceName));
	}
}
bool LifeManageWindow::checkState(int row, const QString &conditionState, const QString &oper)
{
	auto state = mModel->item(row, InstanceState_Column)->text();		//获取组件当前状态
	auto comName = mModel->item(row, ComponentName_Column)->text();		//获取组件名
	auto instanceName = mModel->item(row, InstanceName_Column)->text(); //获取实例名
	if (!conditionState.split("/").contains(state))
	{
		QString msg = QStringLiteral("组件 <strong>%1</strong> 的一个名为<strong> %2 </strong>的实例\
								   当前的状态是：<span style='color:red'>%3</span> ,\
								   只有处在 <span style='color:blue'>%4</span> 状态的实例才能执行 <strong>%5</strong> 操作！");
		QString text = msg.arg(comName, instanceName, state, conditionState, oper);
		QString title = QString("%1%2").arg(oper, QStringLiteral("失败"));
		QMessageBox::warning(this, title, text);
		return false;
	}
	return true;
}
QVector<int> LifeManageWindow::getSelectedRows()
{
	QVector<int> result;
	QItemSelectionModel *selections = ui.tableView->selectionModel(); //调用QT自带的getSelectedRows会报错，应该是QT的问题
	if (selections != nullptr)
	{
		const QItemSelection ranges = selections->selection(); //具体https://blog.csdn.net/ljqiankun/article/details/50970423
		for (auto it = ranges.begin(); it != ranges.end(); it++)
		{
			for (int r = it->top(); r <= it->bottom(); r++)
			{
				result.push_back(r);
			}
		}
	}
	return result;
}